<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 6.3.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"reiholdchen.gitee.io","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
  </script>

  <meta name="description" content="Overview本文是 ld 链接器的手册的阅读笔记, 记录里面的重点.ld 结合了许多object file 和 archive files，relocates 它们的数据并绑定 symbol references。通常编译程序的最后一步是运行 ld。ld 接受以 AT&amp;T’s Link Editor Command Language 的超集编写的 Linker Command Lang">
<meta property="og:type" content="article">
<meta property="og:title" content="How to use linker ?">
<meta property="og:url" content="http://reiholdchen.gitee.io/2023/04/03/how-to-use-linker/index.html">
<meta property="og:site_name" content="Reihold Chen&#39; Blogs">
<meta property="og:description" content="Overview本文是 ld 链接器的手册的阅读笔记, 记录里面的重点.ld 结合了许多object file 和 archive files，relocates 它们的数据并绑定 symbol references。通常编译程序的最后一步是运行 ld。ld 接受以 AT&amp;T’s Link Editor Command Language 的超集编写的 Linker Command Lang">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2023-04-03T11:36:34.000Z">
<meta property="article:modified_time" content="2023-04-06T03:13:46.959Z">
<meta property="article:author" content="Reihold Chen">
<meta property="article:tag" content="开发工具">
<meta property="article:tag" content="编译工具链">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="http://reiholdchen.gitee.io/2023/04/03/how-to-use-linker/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>How to use linker ? | Reihold Chen' Blogs</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">Reihold Chen' Blogs</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-about">

    <a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>

  </li>
  </ul>
</nav>




</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://reiholdchen.gitee.io/2023/04/03/how-to-use-linker/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="Reihold Chen">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Reihold Chen' Blogs">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          How to use linker ?
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2023-04-03 19:36:34" itemprop="dateCreated datePublished" datetime="2023-04-03T19:36:34+08:00">2023-04-03</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2023-04-06 11:13:46" itemprop="dateModified" datetime="2023-04-06T11:13:46+08:00">2023-04-06</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E7%BC%96%E8%AF%91%E5%B7%A5%E5%85%B7%E9%93%BE/" itemprop="url" rel="index"><span itemprop="name">编译工具链</span></a>
                </span>
                  ，
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E7%BC%96%E8%AF%91%E5%B7%A5%E5%85%B7%E9%93%BE/%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%8E%AF%E5%A2%83/" itemprop="url" rel="index"><span itemprop="name">二进制环境</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h1 id="Overview"><a href="#Overview" class="headerlink" title="Overview"></a>Overview</h1><p>本文是 ld 链接器的手册的阅读笔记, 记录里面的重点.<br>ld 结合了许多object file 和 archive files，relocates 它们的数据并绑定 symbol references。通常编译程序的最后一步是运行 ld。<br>ld 接受以 AT&amp;T’s Link Editor Command Language 的超集编写的 Linker Command Language 文件，以提供对链接过程的明确和全面的控制。</p>
<span id="more"></span>

<hr>
<h1 id="链接器-使用选项"><a href="#链接器-使用选项" class="headerlink" title="链接器 使用选项"></a>链接器 使用选项</h1><p>链接器是一个将目标文件或库文件链接成可执行文件或共享库文件的程序。链接器有许多选项，以下是其中一些常用的重要选项：</p>
<ol>
<li><strong>-o</strong>：指定输出文件名。</li>
<li><strong>-L</strong>：指定库文件搜索路径。</li>
<li><strong>-l</strong>：指定需要链接的库文件名。</li>
<li><strong>-static</strong>：生成静态链接的可执行文件或库文件。</li>
<li><strong>-shared</strong>：生成动态链接的共享库文件。</li>
<li><strong>-export-dynamic</strong>：允许共享库文件中的符号被动态加载。</li>
<li><strong>-Bsymbolic</strong>：强制将符号绑定到定义符号的共享库中，而不是全局符号表中。</li>
<li>**-Wl,**：将选项传递给底层链接器。</li>
</ol>
<hr>
<h1 id="linker-script"><a href="#linker-script" class="headerlink" title="linker script"></a>linker script</h1><p>每个链接都由链接脚本(link script)控制。该脚本是用链接器命令语言编写的。<br>链接描述文件的主要目的是描述输入文件中的段应如何映射到输出文件，并控制输出文件的内存布局。大多数链接描述文件只做这个。</p>
<h2 id="link-script-基本概念"><a href="#link-script-基本概念" class="headerlink" title="link script 基本概念"></a>link script 基本概念</h2><p>链接器将输入文件组合成一个输出文件。输出文件和每个输入文件都采用称为<strong>object file</strong>格式的特殊数据格式。每个文件称为<strong>object file</strong>。输出文件通常称为可执行文件，但出于我们的目的，我们也将其称为<strong>object file</strong>。每个目标文件都有一个<strong>sections</strong>列表。我们有时将输入文件中的一个<strong>section</strong>称为 <strong>input section</strong> ；类似地，输出文件中的一个section是一个 <strong>output section</strong>。<br>目标文件中的每个section都有一个name和一个size。大多数section还有一个关联的data block，称为 section contents。一个部分可能被标记为 loadable，这意味着当输出文件运行时，内容应该被加载到内存中。一个没有内容的section可能是allocatable，这意味着内存中的一个区域应该被预留，但没有什么特别的东西应该被加载到那里（在某些情况下，这个内存必须被清零）。既不可loadable也不可 allocatable 的 section 通常包含某种调试信息。<br>可以使用objdump -h 查看object文件中的sections。<br>每个object file 还有一个symbols列表，称为symbol table。符号可以是已定义或未定义的。每个符号都有一个名称，每个定义的符号都有一个地址，以及其他信息。如果将 C 或 C++ 程序编译成目标文件，您将获得每个已定义函数和全局或静态变量的已定义符号。输入文件中引用的每个未定义的函数或全局变量都将成为未定义的符号。使用nm或者onjdump -t 查看object 文件中的符号。</p>
<h3 id="VMA-amp-LMA"><a href="#VMA-amp-LMA" class="headerlink" title="VMA &amp; LMA"></a>VMA &amp; LMA</h3><blockquote>
<p>vma: <a target="_blank" rel="noopener" href="https://sourceware.org/binutils/docs/ld/Output-Section-Address.html">https://sourceware.org/binutils/docs/ld/Output-Section-Address.html</a></p>
<p>lma: <a target="_blank" rel="noopener" href="https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html">https://sourceware.org/binutils/docs/ld/Output-Section-LMA.html</a></p>
<p><a target="_blank" rel="noopener" href="https://sourceware.org/binutils/docs/ld/Basic-Script-Concepts.html">https://sourceware.org/binutils/docs/ld/Basic-Script-Concepts.html</a> </p>
</blockquote>
<p>总结: LMA(load address)指定在rom中存放的地址, VMA(virtual address)指定在runtime的地址(RAM).<br>LMA地址由 <code>AT</code> or <code>AT&gt;</code> 关键字指定。这指定了该部分的确切加载地址。 <code>AT&gt;</code> 关键字将内存区域的名称作为参数。内存区域指令在 <code>MEMORY</code> 命令中定义。<br>如果 AT 和 AT&gt; 都没有为可分配的部分指定，链接器将使用以下试探法来确定加载地址：</p>
<ul>
<li>如果该部分有一个特定的 VMA 地址，那么它也被用作 LMA 地址。</li>
<li>如果该部分不可分配，则将其 LMA 设置为其 VMA。</li>
<li>否则，如果可以找到与当前部分兼容的内存区域，并且该区域至少包含一个部分，则设置 LMA，因此 VMA 和 LMA 之间的差异与 VMA 和 LMA 之间的差异相同定位区域的最后一部分。</li>
<li>如果没有声明内存区域，则在上一步中使用覆盖整个地址空间的默认区域。</li>
<li>如果找不到合适的区域，或者没有前面的部分，则将 LMA 设置为等于 VMA。</li>
</ul>
<p>此功能旨在简化 ROM 映像的构建。例如，以下链接器脚本创建了三个输出部分：一个称为“.text”，从 0x1000 开始，一个称为“.mdata”，即使其 VMA 为 0x2000，它也会在“.text”部分的末尾加载，还有一个名为“.bss”的文件用于在地址 0x3000 处保存未初始化的数据。符号 _data 定义为值 0x2000，这表明位置计数器保存的是 VMA 值，而不是 LMA 值。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">SECTIONS</span><br><span class="line">  &#123;</span><br><span class="line">  .text 0x1000 : &#123; *(.text) _etext = . ; &#125;</span><br><span class="line">  .mdata 0x2000 :</span><br><span class="line">    AT ( ADDR (.text) + SIZEOF (.text) )</span><br><span class="line">    &#123; _data = . ; *(.data); _edata = . ;  &#125;</span><br><span class="line">  .bss 0x3000 :</span><br><span class="line">    &#123; _bstart = . ;  *(.bss) *(COMMON) ; _bend = . ;&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>使用此链接器脚本生成的程序一起使用的运行时初始化代码将包括如下内容，以将初始化数据从 ROM 映像复制到其运行时地址。请注意此代码如何利用链接描述文件定义的符号。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">extern char _etext, _data, _edata, _bstart, _bend;</span><br><span class="line">char *src = &amp;_etext;</span><br><span class="line">char *dst = &amp;_data;</span><br><span class="line"></span><br><span class="line">/* ROM has data at end of text; copy it.  */</span><br><span class="line">while (dst &lt; &amp;_edata)</span><br><span class="line">  *dst++ = *src++;</span><br><span class="line"></span><br><span class="line">/* Zero bss.  */</span><br><span class="line">for (dst = &amp;_bstart; dst&lt; &amp;_bend; dst++)</span><br><span class="line">  *dst = 0;</span><br></pre></td></tr></table></figure>
<h2 id="链接脚本-格式"><a href="#链接脚本-格式" class="headerlink" title="链接脚本 格式"></a>链接脚本 格式</h2><p>link script 是文本文件.<br>将 link script 编写为一系列命令。每个命令要么是一个关键字，可能后跟参数，要么是对符号的赋值。可以使用分号分隔命令。空格通常被忽略。<br>通常可以直接输入文件或格式名称等字符串。如果文件名中包含逗号这样的字符，该字符用于分隔文件名，则可以将文件名放在双引号中。不能在文件名中使用双引号。<br>可以像在 C 中一样在链接描述文件中包含注释，由“&#x2F;<em>”和“</em>&#x2F;”分隔。与在 C 中一样，注释在句法上等同于空格。</p>
<h2 id="SECTIONS-command"><a href="#SECTIONS-command" class="headerlink" title="SECTIONS command"></a>SECTIONS command</h2><p>SECTIONS 命令告诉链接器如何将输入节映射到输出节，以及如何将输出节放入内存中。<br>SECTIONS 命令的格式为：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">SECTIONS</span><br><span class="line">&#123;</span><br><span class="line">  sections-command</span><br><span class="line">  sections-command</span><br><span class="line">  …</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>每个 sections-command 可以是以下之一：</p>
<ul>
<li>an ENTRY command (see <a target="_blank" rel="noopener" href="https://sourceware.org/binutils/docs/ld/Entry-Point.html">Entry command</a>)</li>
<li>a symbol assignment (see <a target="_blank" rel="noopener" href="https://sourceware.org/binutils/docs/ld/Assignments.html">Assigning Values to Symbols</a>)</li>
<li>an output section description</li>
<li>an overlay description</li>
</ul>
<p>如果您不在链接描述文件中使用 SECTIONS 命令，链接器会将每个输入节放入同名的输出节中，并按照这些节在输入文件中首次遇到的顺序排列。例如，如果所有输入节都出现在第一个文件中，则输出文件中节的顺序将与第一个输入文件中的顺序匹配。第一部分的地址为零。<br>其中， <code>output section description</code> 和 <code>overlay description</code> 比较重要， 出现的比较多， 配置的选项也比较多， 下面重点介绍。</p>
<h3 id="output-section-description"><a href="#output-section-description" class="headerlink" title="output section description"></a>output section description</h3><blockquote>
<p><a target="_blank" rel="noopener" href="https://sourceware.org/binutils/docs/ld/Output-Section-Description.html">https://sourceware.org/binutils/docs/ld/Output-Section-Description.html</a></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">section [address] [(type)] :</span><br><span class="line">  [AT(lma)]</span><br><span class="line">  [ALIGN(section_align) | ALIGN_WITH_INPUT]</span><br><span class="line">  [SUBALIGN(subsection_align)]</span><br><span class="line">  [constraint]</span><br><span class="line">  &#123;</span><br><span class="line">    output-section-command</span><br><span class="line">    output-section-command</span><br><span class="line">    …</span><br><span class="line">  &#125; [&gt;region] [AT&gt;lma_region] [:phdr :phdr …] [=fillexp] [,]</span><br></pre></td></tr></table></figure>
<p>每个 output-section-command 可以是以下之一：</p>
<ul>
<li>a symbol assignment (see <a target="_blank" rel="noopener" href="https://sourceware.org/binutils/docs/ld/Assignments.html">Assigning Values to Symbols</a>) </li>
<li>an input section description (see <a target="_blank" rel="noopener" href="https://sourceware.org/binutils/docs/ld/Input-Section.html">Input Section Description</a>) </li>
<li>data values to include directly (see <a target="_blank" rel="noopener" href="https://sourceware.org/binutils/docs/ld/Output-Section-Data.html">Output Section Data</a>) </li>
<li>a special output section keyword (see <a target="_blank" rel="noopener" href="https://sourceware.org/binutils/docs/ld/Output-Section-Keywords.html">Output Section Keywords</a>)</li>
</ul>
<p>介绍一下花括号外面的一些属性设置：</p>
<blockquote>
<p><a target="_blank" rel="noopener" href="https://sourceware.org/binutils/docs/ld/Output-Section-Attributes.html">https://sourceware.org/binutils/docs/ld/Output-Section-Attributes.html</a></p>
</blockquote>
<h4 id="address-address-（Output-Section-Address）："><a href="#address-address-（Output-Section-Address）：" class="headerlink" title="address [address]（Output Section Address）："></a>address [address]（Output Section Address）：</h4><p>该地址是输出部分的 VMA（虚拟内存地址）的表达式。该地址是可选的，但如果提供了，则输出地址将完全按照指定设置。<br>如果未指定输出地址，则将根据下面的启发式方法为该部分选择一个。该地址将被调整以适应输出部分的对齐要求。对齐要求是输出部分中包含的任何输入部分的最严格对齐。</p>
<ul>
<li><code>&gt;region</code> 选项设置了。If an output memory region is set for the section then it is added to this region and its address will be the next free address in that region.</li>
<li>memory设置的内存区域中符合section属性的内存区域。If the MEMORY command has been used to create a list of memory regions then the first region which has attributes compatible with the section is selected to contain it. The section’s output address will be the next free address in that region; <a target="_blank" rel="noopener" href="https://sourceware.org/binutils/docs/ld/MEMORY.html">MEMORY Command</a>.</li>
<li>If no memory regions were specified, or none match the section then the output address will be based on the current value of the location counter.</li>
</ul>
<h4 id="type"><a href="#type" class="headerlink" title="type"></a>type</h4><table>
<thead>
<tr>
<th>类型</th>
<th>含义</th>
</tr>
</thead>
<tbody><tr>
<td>NOLOAD</td>
<td>该部分应标记为不可加载，以便在程序运行时不会将其加载到内存中。</td>
</tr>
<tr>
<td>READONLY</td>
<td>该部分应标记为只读。</td>
</tr>
<tr>
<td>DSECT COPY INFO OVERLAY</td>
<td>这些类型名称支持向后兼容，很少使用。它们都有相同的效果：该段应该被标记为不可分配，这样程序运行时就不会为该段分配内存。</td>
</tr>
<tr>
<td>TYPE &#x3D; type</td>
<td>设置类型</td>
</tr>
<tr>
<td>READONLY ( TYPE &#x3D; type )</td>
<td>结合了 <code>READONLY</code> 和  <code>TYPE = type</code></td>
</tr>
</tbody></table>
<h4 id="Output-Section-LMA-AT-lma-和-AT-gt-lma-region"><a href="#Output-Section-LMA-AT-lma-和-AT-gt-lma-region" class="headerlink" title="Output Section LMA [AT(lma)] 和 [AT&gt;lma_region]"></a>Output Section LMA [AT(lma)] 和 [AT&gt;lma_region]</h4><p>每个 section 都有一个虚拟地址（VMA）和一个加载地址（LMA）。虚拟地址由前面描述的输出部分地址指定。加载地址由 <code>AT</code>或 <code>AT&gt;</code> 关键字指定。<br><code>AT</code> 关键字将表达式作为参数。这指定了该 section 的确切加载地址。 <code>AT&gt;</code> 关键字将内存区域的名称作为参数。内存区域由 memory 指令指定。<br>如果 <code>AT</code> 和 <code>AT&gt;</code> 都没有为可分配的部分指定，链接器将使用以下试探法来确定加载地址：</p>
<ul>
<li>（如果有vma地址，使用vma地址）If the section has a specific VMA address, then this is used as the LMA address as well.</li>
<li>（如果type是noload的， 设置为vma）If the section is not allocatable then its LMA is set to its VMA.</li>
<li>Otherwise if a memory region can be found that is compatible with the current section, and this region contains at least one section, then the LMA is set so the difference between the VMA and LMA is the same as the difference between the VMA and LMA of the last section in the located region.</li>
<li>If no memory regions have been declared then a default region that covers the entire address space is used in the previous step.</li>
<li>If no suitable region could be found, or there was no previous section then the LMA is set equal to the VMA.</li>
</ul>
<h4 id="gt-region-Output-Section-Region"><a href="#gt-region-Output-Section-Region" class="headerlink" title="[&gt;region]  Output Section Region"></a>[&gt;region]  Output Section Region</h4><p>可以使用“&gt;region”将一个部分分配给先前定义的内存区域。<br>这是一个简单的例子：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">MEMORY &#123; rom : ORIGIN = 0x1000, LENGTH = 0x1000 &#125; </span><br><span class="line">SECTIONS &#123; ROM : &#123; *(.text) &#125; &gt;rom &#125;</span><br></pre></td></tr></table></figure>

<h2 id="MEMORY-command"><a href="#MEMORY-command" class="headerlink" title="MEMORY command"></a>MEMORY command</h2><p>链接器的默认配置允许分配所有可用内存。您可以使用 <code>MEMORY</code> 命令覆盖它。<br>MEMORY 命令描述目标中内存块的位置和大小。您可以使用它来描述链接器可以使用哪些内存区域，以及它必须避免使用哪些内存区域。然后，您可以将 sections 分配给特定的内存区域。链接器将根据内存区域设置 section 地址，并对区域太满发出警告。链接器不会随机调整部分以适应可用区域。<br>链接描述文件可能包含 <code>MEMORY</code> 命令的多次使用，但是，所有定义的内存块都被视为好像它们是在单个 <code>MEMORY</code> 命令中指定的一样。<code>MEMORY</code> 的语法是：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">MEMORY</span><br><span class="line">  &#123;</span><br><span class="line">    name [(attr)] : ORIGIN = origin, LENGTH = len</span><br><span class="line">    …</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure>
<p>该名称是链接描述文件中用来指代该区域的名称。区域名称在链接描述文件之外没有任何意义。区域名称存储在单独的名称空间中，不会与symbol names、file names或 section names冲突。每个内存区域在 MEMORY 命令中必须有一个不同的名称。但是，您可以使用 <a target="_blank" rel="noopener" href="https://sourceware.org/binutils/docs/ld/REGION_005fALIAS.html">Assign alias names to memory regions</a> 命令将以后的别名添加到现有内存区域。</p>
<h3 id="属性-attr"><a href="#属性-attr" class="headerlink" title="属性 [(attr)]"></a>属性 [(attr)]</h3><p><strong>attr 字符串</strong>是一个可选的属性列表，用于指定是否将特定内存区域用于未在链接描述文件中显式映射的输入节。如 SECTIONS 命令中所述，如果您没有为某些输入节指定输出节，链接器将创建一个与输入节同名的输出节。如果您定义了区域属性，链接器将使用它们来为它创建的输出段选择内存区域。<br>attr 字符串必须仅包含以下字符：</p>
<table>
<thead>
<tr>
<th>属性字符</th>
<th>含义</th>
</tr>
</thead>
<tbody><tr>
<td>R</td>
<td>Read-only section</td>
</tr>
<tr>
<td>W</td>
<td>Read&#x2F;write section</td>
</tr>
<tr>
<td>X</td>
<td>Executable section</td>
</tr>
<tr>
<td>A</td>
<td>Allocatable section</td>
</tr>
<tr>
<td>I</td>
<td>Initialized section</td>
</tr>
<tr>
<td>L</td>
<td>Same as ‘I’</td>
</tr>
<tr>
<td>!</td>
<td>反转后面任何属性的含义</td>
</tr>
</tbody></table>
<h3 id="内存区域起始地址-origin"><a href="#内存区域起始地址-origin" class="headerlink" title="内存区域起始地址 origin"></a>内存区域起始地址 origin</h3><p><code>origin</code>  是内存区域起始地址的数值表达式。该表达式的计算结果必须为常量，并且不能包含任何符号。关键字 <code>ORIGIN</code> 可以缩写为 <code>org</code> 或 <code>o</code>（但不能缩写为 ORG）。</p>
<h3 id="内存区域长度-len"><a href="#内存区域长度-len" class="headerlink" title="内存区域长度 len"></a>内存区域长度 len</h3><p><code>len</code> 是内存区域大小（以字节为单位）的表达式。与原点表达式一样，该表达式必须仅为数值且计算结果必须为常量。关键字 LENGTH 可以缩写为 len 或 l。</p>
<h3 id="memory-region-相关计算函数"><a href="#memory-region-相关计算函数" class="headerlink" title="memory region 相关计算函数"></a>memory region 相关计算函数</h3><p>可以通过 ORIGIN(memory) 和 LENGTH(memory) 函数访问表达式中内存的起点和长度：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">_fstack = ORIGIN(ram) + LENGTH(ram) - 4;</span><br></pre></td></tr></table></figure>
<h2 id="杂项命令"><a href="#杂项命令" class="headerlink" title="杂项命令"></a>杂项命令</h2><h3 id="entry-point"><a href="#entry-point" class="headerlink" title="entry point"></a>entry point</h3><p>程序中执行的第一条指令称为入口点。您可以使用 ENTRY 链接描述文件命令来设置入口点。参数是一个符号名称：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ENTRY(symbol)</span><br></pre></td></tr></table></figure>
<p>有几种方法可以设置入口点。链接器将通过按顺序尝试以下每种方法来设置入口点，并在其中一种方法成功时停止：</p>
<ul>
<li>“-e”条目命令行选项；</li>
<li>链接描述文件中的 ENTRY(symbol) 命令；</li>
<li>目标特定符号的值（如果已定义）；对于许多目标来说，这是开始，但是基于 PE 和 BeOS 的系统例如检查可能的条目符号列表，与找到的第一个匹配。</li>
<li>代码部分第一个字节的地址，如果存在并且正在创建可执行文件 - 代码部分通常是“.text”，但也可以是其他内容；</li>
<li>地址 0。</li>
</ul>
<h3 id="处理文件"><a href="#处理文件" class="headerlink" title="处理文件"></a>处理文件</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">INCLUDE filename</span><br></pre></td></tr></table></figure>
<p>此时包括链接器脚本文件名。该文件将在当前目录和使用 -L 选项指定的任何目录中搜索。您最多可以嵌套 10 层深度的 INCLUDE 调用。<br>您可以将 INCLUDE 指令放在顶层、MEMORY 或 SECTIONS 命令中或输出节描述中。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">SEARCH_DIR(path)</span><br></pre></td></tr></table></figure>
<p>SEARCH_DIR 命令将路径添加到 ld 查找存档库的路径列表中。使用 SEARCH_DIR(path) 与在命令行中使用“-L path”完全一样（请参阅命令行选项）。如果两者都使用，则链接器将搜索这两个路径。首先搜索使用命令行选项指定的路径。</p>
<h3 id="处理-object-file"><a href="#处理-object-file" class="headerlink" title="处理 object file"></a>处理 object file</h3><p><code>OUTPUT_FORMAT(default, big, little)</code></p>
<h3 id="给-memory-regions-安排别名"><a href="#给-memory-regions-安排别名" class="headerlink" title="给 memory regions 安排别名"></a>给 memory regions 安排别名</h3><p><code>REGION_ALIAS(alias, region)</code></p>
<hr>
<h1 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h1><ul>
<li>从零实现链接器: <a target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1D8411j7fo/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=3311a3bacb19a1eb2a458d56609d4ce7">https://www.bilibili.com/video/BV1D8411j7fo/?spm_id_from&#x3D;333.1007.top_right_bar_window_history.content.click&amp;vd_source&#x3D;3311a3bacb19a1eb2a458d56609d4ce7</a></li>
<li>链接器ld手册: <a target="_blank" rel="noopener" href="https://sourceware.org/binutils/docs/ld/">https://sourceware.org/binutils/docs/ld/</a></li>
<li>链接脚本语言手册: <a target="_blank" rel="noopener" href="https://sourceware.org/binutils/docs/ld/Scripts.html">https://sourceware.org/binutils/docs/ld/Scripts.html</a></li>
<li>可以看下这个人的相关博客: <a target="_blank" rel="noopener" href="http://wen00072.github.io/">http://wen00072.github.io/</a></li>
<li>简明例子: <ul>
<li><a target="_blank" rel="noopener" href="http://wen00072.github.io/blog/2014/03/14/study-on-the-linker-script/">http://wen00072.github.io/blog/2014/03/14/study-on-the-linker-script/</a></li>
<li><a target="_blank" rel="noopener" href="https://codeantenna.com/a/4xqX4RBtNv">https://codeantenna.com/a/4xqX4RBtNv</a></li>
</ul>
</li>
</ul>

    </div>

    
    
    

      <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/" rel="tag"># 开发工具</a>
              <a href="/tags/%E7%BC%96%E8%AF%91%E5%B7%A5%E5%85%B7%E9%93%BE/" rel="tag"># 编译工具链</a>
          </div>

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2023/04/02/what-value-shuold-we-create-as-a-PLCer-1/" rel="prev" title="作为编译领域从业者，应该创造什么价值?">
      <i class="fa fa-chevron-left"></i> 作为编译领域从业者，应该创造什么价值?
    </a></div>
      <div class="post-nav-item"></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#Overview"><span class="nav-number">1.</span> <span class="nav-text">Overview</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E9%93%BE%E6%8E%A5%E5%99%A8-%E4%BD%BF%E7%94%A8%E9%80%89%E9%A1%B9"><span class="nav-number">2.</span> <span class="nav-text">链接器 使用选项</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#linker-script"><span class="nav-number">3.</span> <span class="nav-text">linker script</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#link-script-%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5"><span class="nav-number">3.1.</span> <span class="nav-text">link script 基本概念</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#VMA-amp-LMA"><span class="nav-number">3.1.1.</span> <span class="nav-text">VMA &amp; LMA</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%93%BE%E6%8E%A5%E8%84%9A%E6%9C%AC-%E6%A0%BC%E5%BC%8F"><span class="nav-number">3.2.</span> <span class="nav-text">链接脚本 格式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#SECTIONS-command"><span class="nav-number">3.3.</span> <span class="nav-text">SECTIONS command</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#output-section-description"><span class="nav-number">3.3.1.</span> <span class="nav-text">output section description</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#address-address-%EF%BC%88Output-Section-Address%EF%BC%89%EF%BC%9A"><span class="nav-number">3.3.1.1.</span> <span class="nav-text">address [address]（Output Section Address）：</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#type"><span class="nav-number">3.3.1.2.</span> <span class="nav-text">type</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Output-Section-LMA-AT-lma-%E5%92%8C-AT-gt-lma-region"><span class="nav-number">3.3.1.3.</span> <span class="nav-text">Output Section LMA [AT(lma)] 和 [AT&gt;lma_region]</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#gt-region-Output-Section-Region"><span class="nav-number">3.3.1.4.</span> <span class="nav-text">[&gt;region]  Output Section Region</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#MEMORY-command"><span class="nav-number">3.4.</span> <span class="nav-text">MEMORY command</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%B1%9E%E6%80%A7-attr"><span class="nav-number">3.4.1.</span> <span class="nav-text">属性 [(attr)]</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F%E8%B5%B7%E5%A7%8B%E5%9C%B0%E5%9D%80-origin"><span class="nav-number">3.4.2.</span> <span class="nav-text">内存区域起始地址 origin</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F%E9%95%BF%E5%BA%A6-len"><span class="nav-number">3.4.3.</span> <span class="nav-text">内存区域长度 len</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#memory-region-%E7%9B%B8%E5%85%B3%E8%AE%A1%E7%AE%97%E5%87%BD%E6%95%B0"><span class="nav-number">3.4.4.</span> <span class="nav-text">memory region 相关计算函数</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%9D%82%E9%A1%B9%E5%91%BD%E4%BB%A4"><span class="nav-number">3.5.</span> <span class="nav-text">杂项命令</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#entry-point"><span class="nav-number">3.5.1.</span> <span class="nav-text">entry point</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%A4%84%E7%90%86%E6%96%87%E4%BB%B6"><span class="nav-number">3.5.2.</span> <span class="nav-text">处理文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%A4%84%E7%90%86-object-file"><span class="nav-number">3.5.3.</span> <span class="nav-text">处理 object file</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%BB%99-memory-regions-%E5%AE%89%E6%8E%92%E5%88%AB%E5%90%8D"><span class="nav-number">3.5.4.</span> <span class="nav-text">给 memory regions 安排别名</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%8F%82%E8%80%83"><span class="nav-number">4.</span> <span class="nav-text">参考</span></a></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">Reihold Chen</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">2</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">3</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">3</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://gitee.com/reiholdchen" title="GitHub → https:&#x2F;&#x2F;gitee.com&#x2F;reiholdchen" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="mailto:reihold@qq.com" title="E-Mail → mailto:reihold@qq.com" rel="noopener" target="_blank"><i class="fa fa-envelope fa-fw"></i>E-Mail</a>
      </span>
  </div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2023</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Reihold Chen</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://pisces.theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Pisces</a> 强力驱动
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>




  















  

  

</body>
</html>
